#include "UnitTest.h"

#ifdef UNIT_TEST

#include "Utils.h"
#include "OAuth.h"
#include "CLogin.h"
#include "CHttpReq.h"
#include "CUser.h"
#include <wx/base64.h>
#include <wx/ffile.h>

extern "C"
{
    void hmac_sha(char* k, int lk, char* d, int ld,  char* out, int t);
}

UnitTest_OAuth::UnitTest_OAuth()
:mReqTokenData(NULL)
,mOauth(NULL)
,mHttpReq(new CHttpReq())
{
    //ctor
    initOauth();
}

UnitTest_OAuth::~UnitTest_OAuth()
{
    delete mHttpReq;
    mHttpReq = NULL;
    //dtor
}

UnitTest_OAuth& UnitTest_OAuth::GetInstance()
{
    static UnitTest_OAuth test_oauth;
    return test_oauth;
}

void UnitTest_OAuth::extractHttpParams()
{
    mHttpReq->extractBaseURLAndQueryParsms("http://api.t.sina.com.cn/statuses/followers.xml?user_id=1233343157&cursor=-1&count=2");
    wxString outStr = mHttpReq->mOauthBaseURL+"\n";
    std::map<wxString, wxString>::iterator itr = mHttpReq->mQueryParamsTable.begin();
    for(;itr!=mHttpReq->mQueryParamsTable.end();++itr)
    {
        outStr<<itr->first<<wxString(":")<<itr->second<<wxString("\n");
    }
    wxMessageBox(outStr);
}

void UnitTest_OAuth::initOauth()
{
    mOauth = &(Oauth::GetInstance());

    delete mReqTokenData;
    mReqTokenData = new OauthData();
    mReqTokenData->consumer_secret= "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98";
    mReqTokenData->consumer_key = "GDdmIQH6jhtmLUypg82g";
    mReqTokenData->nonce = "QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk";
    mReqTokenData->signature_method = "HMAC-SHA1";
    mReqTokenData->timestamp = "1272323042";
    mReqTokenData->version = "1.0";
    mReqTokenData->callback = "http://localhost:3005/the_dance/process_callback?service_provider_id=11";

     mOauth->mOauthData = mReqTokenData;
}

wxString UnitTest_OAuth::getBaseString()
{
    if(NULL == mOauth)
        mOauth = &(Oauth::GetInstance());
    return mOauth->getBaseString("https://api.t.sina.com.cn/oauth/request_token", HTTP_METHOD_POST, false);
}

wxString UnitTest_OAuth::signRequest()
{
    if(NULL == mOauth)
        mOauth = &(Oauth::GetInstance());
    mOauth->signRequest(mOauth->getBaseString("https://api.t.sina.com.cn/oauth/request_token", HTTP_METHOD_POST, false));
    return mReqTokenData->signature;
}

wxString UnitTest_OAuth::HMAC_SHA1()
{
    //Test case 1 from http://oauth.net/core/1.0/#RFC2104
    wxString data("GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1");
    data<<wxString("%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal");
    wxString key("kd94hf93k423kf44&pfkkdhi9sl3r4s00");

    //wxString correct_digest("tR3+Ty81lMeYAr/Fid0kMTYa/WM=");

    char dest[OAUTH_SHA1_BUFFER_SIZE];
    memset( dest, 0, OAUTH_SHA1_BUFFER_SIZE );

    hmac_sha( key.char_str(),
                    key.Length(),
                    data.char_str(),
                    data.Length(),
                    dest,
                    OAUTH_SHA1_BUFFER_SIZE);

    return wxBase64Encode(dest, strlen(dest));
}

wxString UnitTest_OAuth::getReqTokenHeader()
{
    if(NULL == mOauth) return "";
    mOauth->signRequest(mOauth->getBaseString("https://api.t.sina.com.cn/oauth/request_token", HTTP_METHOD_POST, false));
    return mOauth->getOauthHeader();
}

wxString UnitTest_OAuth::getNonce()
{
    if(mOauth==NULL)
        return "";
    else
        return mOauth->getNonce();
}

wxString UnitTest_OAuth::getTimestamp()
{
    if(mOauth==NULL)
        return "";
    else
        return wxString("")<<mOauth->getTimestamp();
}

///---------------------------------------------------------------------------------------

UnitTest_Login::UnitTest_Login()
{
    InitLogin();
}

UnitTest_Login:: ~UnitTest_Login()
{
    DestroyLogin();
}

UnitTest_Login& UnitTest_Login::GetInstance()
{
    static UnitTest_Login login;
    return login;
}

void UnitTest_Login::InitLogin()
{
    m_pLogin = new CLogin();
}

void UnitTest_Login::DestroyLogin()
{
    delete m_pLogin;
    m_pLogin = NULL;
}

void UnitTest_Login::getRequestToken()
{
    m_pLogin->getToken(CLogin::REQUEST_TOKEN);
}

void UnitTest_Login::getAccessToken(const wxString& _PIN)
{
    m_pLogin->getToken(CLogin::ACCESS_TOKEN, _PIN);
}

///--------------------------------------------------------------------

UnitTest_XMLValidator::UnitTest_XMLValidator()
:mpCUser(new CUser())
,mpFile(new wxFFile())
,mFileContent("")
,mpValidator(&XMLIntegrityValidator::GetInstance())
{

}

UnitTest_XMLValidator:: ~UnitTest_XMLValidator()
{
    delete mpCUser;
    delete mpFile;
    mpCUser = NULL;
    mpFile = NULL;
}

UnitTest_XMLValidator& UnitTest_XMLValidator::GetInstance()
{
    static UnitTest_XMLValidator xmlV;
    return xmlV;
}

std::map<wxString, std::vector<size_t> >&
UnitTest_XMLValidator::getStats()
{
    assert(NULL != mpValidator);
    return mpValidator->m_statsData;
}

std::vector<std::map<wxString, wxString> >&
UnitTest_XMLValidator::getUserData()
{
    assert(NULL != mpCUser);
    return mpCUser->getUser();
}

bool UnitTest_XMLValidator::readXML(const wxString& fileName)
{
    return   NULL != mpFile &&
                mpFile->Open(fileName) &&
                mpFile->ReadAll(&mFileContent) &&
                mpFile->Close();
}

bool UnitTest_XMLValidator::parseXML()
{
    return mpCUser->startParsing(mFileContent);
}

wxString UnitTest_XMLValidator::sampleXML_Test()
{
    assert(NULL != mpValidator);
    mpValidator->sampleXML(mpCUser->getUser());

    wxString outStr("");
    std::map<wxString, std::vector<size_t> >::iterator itr = mpValidator->m_statsData.begin();
    for(;itr!=mpValidator->m_statsData.end();++itr)
    {
        outStr<<itr->first<<": "<<itr->second.size()<<"\n";
    }
    outStr<<"\n\nTotal tags: "<<mpValidator->m_statsData.size();
    return outStr;
}

wxString UnitTest_XMLValidator::validateXML_Test()
{
    assert(NULL != mpValidator);
    mpValidator->sampleXML(mpCUser->getUser());
    if(!mpValidator->isValid(mpCUser->getUser()))
    {
        return wxString("Errors Found: ")<<mpValidator->m_errors.size();
    }
    else
    {
        return "No Error";
    }
}

wxString UnitTest_XMLValidator::XMLRefFind_Test()
{
    assert(NULL != mpValidator);
    mpValidator->sampleXML(mpCUser->getUser());
    if(! mpValidator->isValid(mpCUser->getUser()))
    {
        mpValidator->findRef(mpCUser->getUser());

        wxString outStr("");

        for(size_t i=0;i<mpValidator->m_errors.size();++i)
        {
            XMLIntegrityValidator::XMLErrorData& error = mpValidator->m_errors[i];
            outStr<<"wrongTag: "<<error.wrongTagName<<"\n";
            outStr<<"nextTag: "<<error.nextTagName<<"\n";
            outStr<<"hitRows: ";
            for(size_t j=0;j<error.hitRows.size();++j)
            {
                outStr<<error.hitRows[j]<<",";
            }
            outStr<<"\n";
            for(size_t k=0;k<error.refMatches.size();++k)
            {
                outStr<<k+1<<"-refName: "<<error.refMatches[k].refName<<"\n";
                outStr<<k+1<<"-weight: "<<error.refMatches[k].weight<<"\n";
                outStr<<k+1<<"-refHitRowSize: "<<error.refMatches[k].refHitRowSize<<"\n";
            }
            outStr<<"\n\n";
        }

        return outStr;
    }
    else
    {
        return "No Error";
    }


}

wxString UnitTest_XMLValidator::XMLErrorCorrection_Test()
{
    assert(NULL != mpValidator);
    mpValidator->sampleXML(mpCUser->getUser());
    if(! mpValidator->isValid(mpCUser->getUser()))
    {
        mpValidator->findRef(mpCUser->getUser());
        mpValidator->correctErrors(mpCUser->getUser());
    }
    return sampleXML_Test();
}


#endif //UNIT_TEST
